#include <logger.h>
#include <napi_call.h>
#include <node_api.h>

napi_value AddNumber(napi_env env, napi_callback_info info)
{
    size_t argc = 2;
    napi_value argv[2] = {};
    NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr));
    if (argc != 2) {
        return nullptr;
    }

    napi_valuetype valtype = napi_undefined;
    NAPI_CALL(env, napi_typeof(env, argv[0], &valtype));
    if (valtype != napi_number) {
        return nullptr;
    }

    NAPI_CALL(env, napi_typeof(env, argv[1], &valtype));
    if (valtype != napi_number) {
        return nullptr;
    }

    double d1 = 0;
    double d2 = 0;
    NAPI_CALL(env, napi_get_value_double(env, argv[0], &d1));
    NAPI_CALL(env, napi_get_value_double(env, argv[1], &d2));

    napi_value retval = nullptr;
    NAPI_CALL(env, napi_create_double(env, d1 + d2, &retval));
    return retval;
}

/* napi_value */
NAPI_MODULE_INIT(/* napi_env env, napi_value exports */)
{
    napi_value addNumber;
    NAPI_CALL(env, napi_create_function(env, "AddNumber", NAPI_AUTO_LENGTH, AddNumber, nullptr, &addNumber));
    NAPI_CALL(env, napi_set_named_property(env, exports, "AddNumber", addNumber));

    napi_value undefined;
    NAPI_CALL(env, napi_get_undefined(env, &undefined));

    napi_value argv[2] = {};
    napi_value retval = nullptr;
    NAPI_CALL(env, napi_create_double(env, 456.123, &argv[0]));
    NAPI_CALL(env, napi_create_double(env, 789.456, &argv[1]));
    NAPI_CALL(env, napi_call_function(env, undefined, addNumber, 2, argv, &retval));
    double doubleVal = 0;
    NAPI_CALL(env, napi_get_value_double(env, retval, &doubleVal));
    VALUE_LOGGER(doubleVal); // doubleVal: '1245.58'

    napi_value global;
    napi_value dateCtor;
    napi_value dateInstance;
    NAPI_CALL(env, napi_get_global(env, &global));
    NAPI_CALL(env, napi_get_named_property(env, global, "Date", &dateCtor));
    NAPI_CALL(env, napi_new_instance(env, dateCtor, 0, nullptr, &dateInstance));
    NAPI_CALL(env, napi_set_named_property(env, exports, "date", dateInstance));
    return exports;
}
